<template>
    <div class="messaebox">
        <div v-for="(item, index) in messages" :key="index" ref="messages">

            <div class="chat">
                <div :class="item.role === 'user' ? 'avatar-right' : 'avatar-left'">
                    <el-checkbox :value="selectedIndices.includes(index)"
                        @change="updateSelectedIndices(index, $event)"></el-checkbox>
                    <el-avatar v-if="item.role === 'user'" class="user-type" shape="square" src="/user.png"></el-avatar>
                    <el-avatar v-if="item.role === 'assistant'" class="user-type" shape="square"
                        src="/logo.jpg"></el-avatar>
                    <el-avatar v-show="index === messages.length - 1 && lodding" shape="square"
                        v-loading="true"></el-avatar>
                </div>
            </div>
            <div :class="item.role === 'user' ? 'txt-right' : 'txt-left'">
                <div :class="['txt', item.role === 'user' ? 'txt-bg' : '']">
                    <div class="txt-left" v-html="md.render(item.content).trim()"></div>
                    <!-- 复制 -->
                    <div class="controller">
                        <el-tooltip content="复制" placement="bottom" effect="light">
                            <i v-if="item.role === 'assistant'" class="el-icon-copy-document"
                                @click="copyText(item.content)"></i>
                        </el-tooltip>
                    </div>
                </div>
            </div>
        </div>


    </div>
</template>

<script>

import MarkdownIt from 'markdown-it';
import markdownItFootnote from 'markdown-it-footnote';
import markdownItTaskLists from 'markdown-it-task-lists';
import markdownItAbbr from 'markdown-it-abbr';
import markdownItContainer from 'markdown-it-container';
import { get_message } from "@/apis/message";
import FileSaver from 'file-saver';

import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
import HtmlDocx from 'html-docx-js/dist/html-docx';

class Export {
    constructor(message) {
        this.dialogue = message;
    }

    dialogueToTxt() {
        // 转换为txt字符串
        let content = "";
        for (let item of this.dialogue) {
            content += `${item.role}: ${item.content};\n`;
        }
        return content;
    }

    dialogueToMarkdown() {
        // 转换为markdown字符串
        let content = "";
        for (let item of this.dialogue) {
            content += `**${item.role}**: ${item.content}\n`;
        }
        return content;
    }

    download(filename, content) {
        // 创建一个Blob对象
        const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
        // 创建一个可以下载的URL
        const url = URL.createObjectURL(blob);
        // 创建一个a标签
        const link = document.createElement("a");
        // 设置a标签的href属性为URL
        link.href = url;
        // 设置a标签的download属性为文件名
        link.download = filename;
        // 触发a标签的点击事件
        link.click();
        // 释放URL
        URL.revokeObjectURL(url);
    }
}

export default {
    name: "MessageInfo",
    data() {
        return {
            md: new MarkdownIt()
                .use(markdownItFootnote)
                .use(markdownItTaskLists, { enabled: true })
                .use(markdownItAbbr)
                .use(markdownItContainer, 'warning'),
            messages: [],
            selectedIndices: [],
            lodding: false,
        }
    },
    watch: {
        messages() {
            this.$nextTick(() => {
                const elements = this.$refs.messages;
                const lastElement = elements[elements.length - 1];
                lastElement.scrollIntoView();
            });
        },
    },

    beforeMount() {
        function markdownTableToTextTable(markdown) {
            // 将Markdown表格的每一行分割成一个数组
            var lines = markdown.split('\n');

            //   
            for (var i = 0; i < lines.length; i++) {

                // 如果该行包含'----'，则跳过该行
                if (lines[i].includes('----')) {
                    lines.splice(i, 1);
                    i--; // 由于删除了一个元素，所以需要将索引减1
                    continue;
                }

                // 使用全局正则表达式匹配Markdown表格的每一列
                var columns = lines[i].split('|').filter(Boolean);
                if (columns) {
                    // 处理每一列
                    for (var j = 0; j < columns.length; j++) {
                        // 去掉列的前后的空白字符
                        columns[j] = columns[j].trim();
                    }
                    // 使用'\t'字符将列连接成一个字符串
                    lines[i] = columns.join('\t');
                }
            }
            // 使用' ;'字符将行连接成一个字符串
            return lines.join('\n');
        }


        localStorage.setItem("selectedIndices", "")
        this.bus.$on("toList", msg => {
            this.messages = msg;
            this.selectedIndices = [];
            const elements = this.$refs.messages;
            const lastElement = elements[elements.length - 1];
            lastElement.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });
        });

        this.bus.$on("group", form => {
            this.messages = JSON.parse(localStorage.getItem('message'))
            this.selectedIndices = [];
        });

        this.bus.$on("exports", type => {
            let messages = []
            let filename = ''
            let content = "";

             // 对 selectedIndices 进行排序
            this.selectedIndices.sort((a, b) => a - b);

            this.selectedIndices.forEach(i => {
                messages.push(this.messages[i])
            })
            if (type === 'excel') {
                filename = "消息列表.xlsx"
                // 将消息转换为对象数组
                let data = messages.map(item => {
                    return {
                        role: item.role,
                        content: markdownTableToTextTable(item.content)
                    };
                });
                // 将对象数组转换为工作表
                const worksheet = XLSX.utils.json_to_sheet(data);
                // 创建工作簿并添加工作表
                const workbook = XLSX.utils.book_new();
                XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
                // 生成 Excel 文件并导出
                const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'binary' });
                let buffer = new ArrayBuffer(excelBuffer.length);
                let view = new Uint8Array(buffer);
                for (let i = 0; i < excelBuffer.length; i++) {
                    view[i] = excelBuffer.charCodeAt(i) & 0xFF;
                }
                const dataBlob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8' });
                // 创建一个可以下载的 URL
                const url = URL.createObjectURL(dataBlob);
                // 创建一个 a 标签
                const link = document.createElement("a");
                // 设置 a 标签的 href 属性为 URL
                link.href = url;
                // 设置 a 标签的 download 属性为文件名
                link.download = filename;
                // 触发 a 标签的点击事件
                link.click();
                // 释放 URL
                URL.revokeObjectURL(url);
                return
            }
            if (type === 'word') {
                filename = "消息列表.docx"
                // 创建一个 HTML 字符串，其中包含所有的消息
                let html = '<html><head><meta charset="UTF-8"></head><body>'
                messages.forEach(item => {
                    html += `<p><b>${item.role}:</b> ${markdownTableToTextTable(item.content)}</p>`
                })
                html += '</body></html>'
                // 使用 html-docx-js 将 HTML 转换为 Word 文档
                let docx = HtmlDocx.asBlob(html);
                // 创建一个可以下载的 URL
                const url = URL.createObjectURL(docx);
                // 创建一个 a 标签
                const link = document.createElement("a");
                // 设置 a 标签的 href 属性为 URL
                link.href = url;
                // 设置 a 标签的 download 属性为文件名
                link.download = filename;
                // 触发 a 标签的点击事件
                link.click();
                // 释放 URL
                URL.revokeObjectURL(url);
                return
            }
            if (type === 'txt') {
                filename = "消息列表.txt"
                for (let item of messages) {
                    let txt = markdownTableToTextTable(item.content)
                    content += `${item.role}:\n ${txt};\n\n`;
                }
            }
            if (type === 'markdown') {
                filename = "消息列表.md"
                for (let item of messages) {

                    content += `**${item.role}**:\n\n ${item.content}\n\n`;
                }
            }
            // 创建一个Blob对象
            const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
            // 创建一个可以下载的URL
            const url = URL.createObjectURL(blob);
            // 创建一个a标签
            const link = document.createElement("a");
            // 设置a标签的href属性为URL
            link.href = url;
            // 设置a标签的download属性为文件名
            link.download = filename;
            // 触发a标签的点击事件
            link.click();
            // 释放URL
            URL.revokeObjectURL(url);
        })

        this.bus.$on('lod', lod => {
            this.lodding = lod
        })
    },
    computed: {},
    methods: {
        updateSelectedIndices(index, checked) {
            if (checked) {
                this.selectedIndices.push(index);
            } else {
                let i = this.selectedIndices.indexOf(index);
                if (i !== -1) {
                    this.selectedIndices.splice(i, 1);
                }
            }
            this.selectedIndices.sort()
            console.log(this.selectedIndices)
            localStorage.setItem("selectedIndices", JSON.stringify(this.selectedIndices))
        },

        //实现复制文本功能
        copyText(text) {
            // 创建一个临时的文本框
            const tempTextArea = document.createElement('textarea');
            // 将文本内容赋值给临时的文本框
            tempTextArea.value = text;
            // 将临时的文本框添加到页面中
            document.body.appendChild(tempTextArea);
            // 选中临时的文本框中的内容
            tempTextArea.select();
            // 执行复制操作
            document.execCommand('copy');
            // 移除临时的文本框
            document.body.removeChild(tempTextArea);
            this.$message({
                message: '复制成功',
                type: 'success'
            });
            this.bus.$emit('copy', text)
        }
    }
}

</script>

<style scoped>
.messaebox {
    padding: 0;
    /*外部间距也是如此设置*/
    margin: 0;
    /*统一设置高度为100%*/
}

.user-type {
    margin: 5px;
    /*margin-top: 5px;*/
}

.controller {
    text-align: right;

}

.controller i {
    font-size: 18px;
    padding: 10px;
    cursor: pointer;
}

.avatar-right {
    display: flex;
    -webkit-box-pack: end;
    -ms-flex-pack: end;
    -webkit-justify-content: flex-end;
    justify-content: flex-end;
    gap: 2
}

.avatar-left {
    display: flex;
    -webkit-box-pack: start;
    -ms-flex-pack: start;
    -webkit-justify-content: flex-start;
    justify-content: flex-start;
    gap: 2
}

.txt-right {
    text-align: right;
    white-space: pre-wrap;
}

.txt-left {
    text-align: left;
}

.txt {
    border-radius: 8px 0 8px 8px;
    background-color: #f7f8fa;
    display: inline-block;
    font-size: 14px;
    color: #111824;
    padding: 0 16px;
    line-height: 20px;
}

.txt-bg {
    background-color: #e1eaff;
}
</style>